//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
//-----------------------------------------------------------------------------
// <auto-generated>
//   This code was generated by a tool.
//
//   Changes to this file may cause incorrect behavior and will be lost if
//   the code is regenerated.
//
//   For more information, see: http://go.microsoft.com/fwlink/?LinkID=623246
// </auto-generated>
//-----------------------------------------------------------------------------
#pragma once

namespace com { namespace microsoft { namespace Samples { namespace SecureInterface {

public interface class ISecureInterfaceConsumer
{
    event Windows::Foundation::TypedEventHandler<SecureInterfaceConsumer^, Platform::Object^>^ IsUpperCaseEnabledChanged;
};

public ref class SecureInterfaceConsumer sealed  : [Windows::Foundation::Metadata::Default] ISecureInterfaceConsumer, ISignalEmitter
{
public:
    SecureInterfaceConsumer(Windows::Devices::AllJoyn::AllJoynBusAttachment^ busAttachment);
    virtual ~SecureInterfaceConsumer();

    // Create a consumer from a device Id asynchronously.
    //
    // This is usually called to create a consumer after the unique name of a producer has been reported
    // in the Added callback on the DeviceWatcher.
    static Windows::Foundation::IAsyncOperation<SecureInterfaceConsumer^>^ FromIdAsync(_In_ Platform::String^ deviceId);

    // Create a consumer from a device Id asynchronously with the provided bus attachment.
    //
    // This is usually called to create a consumer after the unique name of a producer has been reported
    // in the Added callback on the DeviceWatcher.
    static Windows::Foundation::IAsyncOperation<SecureInterfaceConsumer^>^ FromIdAsync(_In_ Platform::String^ deviceId, _In_ Windows::Devices::AllJoyn::AllJoynBusAttachment^ busAttachment);

    int32 SecureInterfaceConsumer::Initialize(_In_ Windows::Devices::AllJoyn::AllJoynServiceInfo^ serviceInfo);

    // "Concatenate two input strings and returns the concatenated string as output"
    // Call the Concatenate method
    Windows::Foundation::IAsyncOperation<SecureInterfaceConcatenateResult^>^ ConcatenateAsync(_In_ Platform::String^ interfaceMemberInStr1, _In_ Platform::String^ interfaceMemberInStr2);

    // This event fires whenever the value of IsUpperCaseEnabled changes.
    virtual event Windows::Foundation::TypedEventHandler<SecureInterfaceConsumer^, Platform::Object^>^ IsUpperCaseEnabledChanged 
    { 
        Windows::Foundation::EventRegistrationToken add(Windows::Foundation::TypedEventHandler<SecureInterfaceConsumer^, Platform::Object^>^ handler) 
        { 
            return _IsUpperCaseEnabledChanged += ref new Windows::Foundation::EventHandler<Platform::Object^>
            ([handler](Platform::Object^ sender, Platform::Object^ args)
            {
                handler->Invoke(safe_cast<SecureInterfaceConsumer^>(sender), safe_cast<Platform::Object^>(args));
            }, Platform::CallbackContext::Same);
        } 
        void remove(Windows::Foundation::EventRegistrationToken token) 
        { 
            _IsUpperCaseEnabledChanged -= token; 
        } 
    internal: 
        void raise(SecureInterfaceConsumer^ sender, Platform::Object^ args) 
        { 
            _IsUpperCaseEnabledChanged(sender, args);
        } 
    }

    // "Determine if the output of the Concatenate method is returned as upper case string or not"
    // Get the value of the IsUpperCaseEnabled property.
    Windows::Foundation::IAsyncOperation<SecureInterfaceGetIsUpperCaseEnabledResult^>^ GetIsUpperCaseEnabledAsync();

    // "Determine if the output of the Concatenate method is returned as upper case string or not"
    // Set the value of the IsUpperCaseEnabled property.
    Windows::Foundation::IAsyncOperation<SecureInterfaceSetIsUpperCaseEnabledResult^>^ SetIsUpperCaseEnabledAsync(_In_ bool value);

    // Used to send signals or register functions to handle received signals.
    property SecureInterfaceSignals^ Signals
    {
        SecureInterfaceSignals^ get() { return m_signals; }
    }

    // Used to get the name of the interface this consumer implements.
    static property Platform::String^ InterfaceName
    {
        Platform::String^ get() { return AllJoynHelpers::MultibyteToPlatformString(m_interfaceName); }
    }

    virtual property Windows::Devices::AllJoyn::AllJoynBusObject^ BusObject
    {
        Windows::Devices::AllJoyn::AllJoynBusObject^ get() { return m_busObject; }
    }

    virtual property Windows::Devices::AllJoyn::AllJoynSession^ Session
    {
        Windows::Devices::AllJoyn::AllJoynSession^ get() { return m_session; }
    }

internal:
    // Consumers do not support property get.
    QStatus OnPropertyGet(_In_ PCSTR interfaceName, _In_ PCSTR propertyName, _Inout_ alljoyn_msgarg val)
    {
        UNREFERENCED_PARAMETER(interfaceName); UNREFERENCED_PARAMETER(propertyName); UNREFERENCED_PARAMETER(val);
        return ER_NOT_IMPLEMENTED;
    }

    // Consumers do not support property set.
    QStatus OnPropertySet(_In_ PCSTR interfaceName, _In_ PCSTR propertyName, _In_ alljoyn_msgarg val)
    {
        UNREFERENCED_PARAMETER(interfaceName); UNREFERENCED_PARAMETER(propertyName); UNREFERENCED_PARAMETER(val);
        return ER_NOT_IMPLEMENTED;
    }

    void OnPropertyChanged(_In_ alljoyn_proxybusobject obj, _In_ PCSTR interfaceName, _In_ const alljoyn_msgarg changed, _In_ const alljoyn_msgarg invalidated);

    property Platform::String^ ServiceObjectPath
    {
        Platform::String^ get() { return m_ServiceObjectPath; }
        void set(Platform::String^ value) { m_ServiceObjectPath = value; }
    }

    property alljoyn_proxybusobject ProxyBusObject
    {
        alljoyn_proxybusobject get() { return m_proxyBusObject; }
        void set(alljoyn_proxybusobject value) { m_proxyBusObject = value; }
    }

private:
    virtual event Windows::Foundation::EventHandler<Platform::Object^>^ _SessionLost;
    virtual event Windows::Foundation::EventHandler<Platform::Object^>^ _SessionMemberAdded;
    virtual event Windows::Foundation::EventHandler<Platform::Object^>^ _SessionMemberRemoved;
    virtual event Windows::Foundation::EventHandler<Platform::Object^>^ _IsUpperCaseEnabledChanged;

    // Register a callback function to handle incoming signals.
    QStatus AddSignalHandler(_In_ alljoyn_busattachment busAttachment, _In_ alljoyn_interfacedescription interfaceDescription, _In_ PCSTR methodName, _In_ alljoyn_messagereceiver_signalhandler_ptr handler);

    // "This signal is emitted when producer sends a text message to consumer"
    static void CallTextSentSignalHandler(_In_ const alljoyn_interfacedescription_member* member, _In_ alljoyn_message message);

    Windows::Devices::AllJoyn::AllJoynBusAttachment^ m_busAttachment;
    Windows::Devices::AllJoyn::AllJoynBusObject^ m_busObject;
    Windows::Devices::AllJoyn::AllJoynSession^ m_session;
    SecureInterfaceSignals^ m_signals;
    Platform::String^ m_ServiceObjectPath;

    alljoyn_proxybusobject m_proxyBusObject;
    alljoyn_sessionlistener m_sessionListener;
    alljoyn_busobject m_nativeBusObject;
    alljoyn_busattachment m_nativeBusAttachment;

    // Used to pass a pointer to this class to callbacks
    Platform::WeakReference* m_weak;

    // This map is required because we need a way to pass the consumer to the signal
    // handlers, but the current AllJoyn C API does not allow passing a context to these
    // callbacks.
    static std::map<alljoyn_interfacedescription, Platform::WeakReference*> SourceInterfaces;

    // The name of the interface this consumer implements.
    static PCSTR m_interfaceName;
};

} } } } 
